package com.qumitech.visualnovel.controller.rest;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.ResultEnum;
import com.qumitech.visualnovel.model.common.BaseResponse;
import com.qumitech.visualnovel.controller.vo.gameData.*;
import com.qumitech.visualnovel.service.gameData.impl.GameDataServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.qumitech.visualnovel.component.util.CommonUtil;
import com.qumitech.visualnovel.component.config.Config;
import java.io.UnsupportedEncodingException;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;

@RestController
@RequestMapping("/api/playGameData")
public class PlayGameDataController {
    private static final Logger log = LoggerFactory.getLogger(PlayGameDataController.class);

    @Autowired
    private GameDataServiceImpl gameDataService;

    @GetMapping
    public BaseRsp getPlayGameData(GameDataQueryDTO gameDataQueryDTO){
        return new BaseRsp(ResultEnum.SUCCESS, gameDataService.getPlayGameData(gameDataQueryDTO));
    }
    @GetMapping(value = "/gameIdOption")
    public BaseRsp getGameIdOption()
    {
        return null;
    }

    @GetMapping(value = "propertyTypeOption")
    public BaseRsp getPropertyTypeOption()
    {
        JSONObject data = JSONObject.parseObject("{\"1\": \"Yo豆\", \"2\": \"钻石\"}");
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @GetMapping(value = "/line/openGameTimes")
    public BaseRsp openGameTimes(@RequestParam(value="startTime") String startTime,
                                      @RequestParam(value="endTime") String endTime,
                                      @RequestParam(value="accountId", required=false) Long accountId,
                                      @RequestParam(value="gameId", required=false) String gameIds)
    {
        String[] gameIdList = null;
        if(gameIds!= null && !gameIds.equals("")) {
            gameIdList = gameIds.split(",");
        }
        JSONObject data = gameDataService.getOpenGameTimesLine(startTime,endTime,accountId,gameIdList);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }
    @GetMapping(value = "/line/openGameNumbers")
    public BaseRsp openGameNumbers(@RequestParam(value="startTime") String startTime,
                                        @RequestParam(value="endTime") String endTime,
                                        @RequestParam(value="gameId", required=false) String gameIds)
    {
        String[] gameIdList = null;
        if(gameIds!= null && !gameIds.equals("")) {
            gameIdList = gameIds.split(",");
        }
        JSONObject data = gameDataService.getOpenGameNumbersLine(startTime,endTime,gameIdList);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }
    @GetMapping(value = "/line/openGameAverageTimes")
    public BaseRsp openGameAverageTimes(@RequestParam(value="startTime") String startTime,
                                        @RequestParam(value="endTime") String endTime,
                                        @RequestParam(value="gameId", required=false) String gameIds)
    {
        String[] gameIdList = null;
        if(gameIds!= null && !gameIds.equals("")) {
            gameIdList = gameIds.split(",");
        }
        JSONObject data = gameDataService.getGameAverageTimesLine(startTime,endTime,gameIdList);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @GetMapping(value = "/list/statistics")
    public BaseRsp getStatisticList(@RequestParam(value="startTime") String startTime,
                                         @RequestParam(value="endTime") String endTime,
                                         @RequestParam(value="accountId", required=false) Long accountId,
                                         @RequestParam(value="gameId", required=false) String gameIds,
                                         @RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                         @RequestParam(value="limit", required=false, defaultValue="20") int limit){
        String[] gameIdList = null;
        if(gameIds!= null && !gameIds.equals("")) {
            gameIdList = gameIds.split(",");
        }
        JSONObject data = gameDataService.getStatisticList(startTime,endTime,accountId,gameIdList, offset, limit);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @GetMapping(value = "/download/list")
    public BaseRsp getDownloadList(
            @RequestParam(value="filePath", required=false, defaultValue="") String filePath,
            @RequestParam(value="offset", required=false, defaultValue="0") String offset,
            @RequestParam(value="limit", required=false, defaultValue="20") String limit) {
        String absPaht = Config.getProperty("app.download.dir") + "/" + filePath;
        int intOffSet = Integer.parseInt(offset);
        int intLimit = Integer.parseInt(limit);
        File[] fileArray = new File(absPaht).listFiles();
        ArrayList<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
        Collections.sort(fileList, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                if (o1.isDirectory() && o2.isFile())
                    return -1;
                if (o1.isFile() && o2.isDirectory())
                    return 1;
                long diff = o1.lastModified() - o2.lastModified();
                if (diff > 0)
                    return -1;
                if (diff < 0)
                    return 1;
                return o1.getName().compareTo(o2.getName());
            }
        });
        JSONObject jsonData = new JSONObject();
        JSONArray jsonDirs = new JSONArray();
        JSONArray jsonFiles = new JSONArray();
        for (int idx=intOffSet; idx<fileList.size() && idx<intOffSet+intLimit; ++idx) {
            File file = fileList.get(idx);
            if (file.isDirectory()) {
                jsonDirs.add(file.getName());
            } else {
                jsonFiles.add(file.getName());
            }
        }
        jsonData.put("dirs", jsonDirs);
        jsonData.put("files", jsonFiles);
        jsonData.put("total", fileList.size());
        return new BaseRsp(ResultEnum.SUCCESS, jsonData);
    }

    @GetMapping(value = "/download/file")
    public void getDownloadFile(
            HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam(value="filePath") String filePath) {
        String absPaht = Config.getProperty("app.download.dir") + "/" + filePath;
        try {
            String fileName = absPaht.substring(absPaht.lastIndexOf("/") + 1);
            String userAgent = request.getHeader("User-Agent");
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            response.setContentType("application/octet-stream; charset=utf-8");
        } catch (UnsupportedEncodingException e) {
            log.error("set response header failed: absPaht={}, error={}", absPaht, e);
            return;
        }

        try {
            CommonUtil.getDownload(response, absPaht);
        } catch (IOException e) {
            log.error("get download file failed: absPaht={}, error={}", absPaht, e);
        }
    }

    @GetMapping(value = "/dataQuery/conf")
    public BaseRsp getDataQueryConfList(
        @RequestParam(value="id", required=false) String id,
        @RequestParam(value="sysUserName", required=false) String sysUserName,
        @RequestParam(value="startTime", required=false) String startTime,
        @RequestParam(value="endTime", required=false) String endTime,
        @RequestParam(value="offset", required=false, defaultValue="0") Integer offset,
        @RequestParam(value="limit", required=false, defaultValue="20") Integer limit) {
        JSONObject data = gameDataService.getDataQueryConfList(id, sysUserName, startTime, endTime, offset, limit);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @PutMapping(value = "/dataQuery/conf/{id}")
    public BaseRsp modDataQueryConf(@PathVariable("id") Long id, @RequestBody GameDataQueryConfDTO conf) {
        gameDataService.modDataQueryConf(id, conf);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    @PostMapping(value = "/dataQuery/conf")
    public BaseRsp addDataQueryConfList(@RequestBody GameDataQueryConfDTO conf) {
        gameDataService.addDataQueryConfList(conf);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    @DeleteMapping(value = "/dataQuery/conf/{id}")
    public BaseRsp delDataQueryConf(@PathVariable("id") Long id) {
        gameDataService.delDataQueryConf(id);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    @GetMapping(value = "/dataQuery/record")
    public BaseRsp getDataQueryRecordList(
        @RequestParam(value="dataName", required=false) String dataName,
        @RequestParam(value="argComments", required=false) String argComments,
        @RequestParam(value="sysUserName", required=false) String sysUserName,
        @RequestParam(value="startTime", required=false) String startTime,
        @RequestParam(value="endTime", required=false) String endTime,
        @RequestParam(value="offset", required=false, defaultValue="0") Integer offset,
        @RequestParam(value="limit", required=false, defaultValue="20") Integer limit) {
        JSONObject data = gameDataService.getDataQueryRecordList(dataName, argComments, sysUserName, startTime, endTime, offset, limit);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @PostMapping(value = "/dataQuery/record")
    public BaseRsp addDataQueryRecordList(@RequestBody GameDataQueryRecordDTO record) {
        gameDataService.addDataQueryRecordList(record);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    @GetMapping(value = "/dataQuery/options/dataNames")
    public BaseRsp getDataQueryOptionsDataNames() {
        JSONArray data = gameDataService.getDataQueryOptionsDataNames();
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @GetMapping(value = "/dataQuery/options/dataTypeNames")
    public BaseRsp getDataQueryOptionsDataTypeNames(@RequestParam(value="dataType", required=false) String dataType) {
        JSONArray data = gameDataService.getDataQueryOptionsDataTypeNames(dataType);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @GetMapping(value = "/dataQuery/permission")
    public BaseRsp getDataQueryPermissionList() {
        JSONObject data = gameDataService.getDataQueryPermissionList();
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @GetMapping(value = "/dataQuery/rolePermission")
    public BaseRsp getDataQueryRolePermission(
        @RequestParam(value="roleId", required=false) Integer roleId,
        @RequestParam(value="type", required=false) String type) {
        JSONObject data = gameDataService.getDataQueryRolePermission(roleId, type);
        return new BaseRsp(ResultEnum.SUCCESS, data);
    }

    @PostMapping(value = "/dataQuery/rolePermission")
    public BaseRsp addDataQueryRolePermission(@RequestBody JSONObject permission) {
        gameDataService.addDataQueryRolePermission(permission);
        return new BaseRsp(ResultEnum.SUCCESS);
    }
}
